
/**
 * 
 * @author Matan Mizrahi,Chen weissman
 * Introduction to computer science, assingment5
 * Date:2.1.2011
 *
 * The Addition class, in which implement the Expression Interface
 * represents the Addition Expression (i.e., a+b, where a and b are expressions as well)
 * An addition expression can be evaluated, derived and return its last operation symbol.
 *
 */

public class Addition implements Expression {
	//*********************************Fields************************************//

    private Expression ex1;
    private Expression ex2;
    //*********************************Constructors******************************//

    /**
     * Constructor that creates an addition expression of composed of the two expressions
     *
     * @param ex1  the ex1 expression
     * @param ex2 the ex2 expression
     * @throws RuntimeException for null input expressions
     */
    public Addition(Expression ex1, Expression ex2) {
        if ((ex1 == null) ||  (ex2 == null)) {
            throw new RuntimeException("Addition constructor got a null argument.");
        }
        this.ex1 = ex1;
        this.ex2 = ex2;
    }
    //*********************************Behavior**********************************//

    /**
     * Returns the last operation symbol of Addition Expression
     *
     * @return String "+" in which represents the last operation
     */
    public String getLastOperationSymbol() {
        return "+";
    }

    /**
     * Evaluate the addition expression
     *
     * @return double that represents the evaluation result of the addition expression
     * @throws Exception  in case the assignment is null or if the variable is not assigned to a value
     */
    public double evaluate(Assignment assign) throws Exception {
              return (ex1.evaluate(assign) + ex2.evaluate(assign));
    }

    /**
     * Derives the addition expression by a variable.
     *
     * @param var the variable to derive by
     * @return the derived expression by param var
     * @throws RuntimeException for a null var
     */

    public Expression derivative(char name) {
        return new Addition(ex1.derivative(name),ex2.derivative(name));
    }

    /**
     * Compares this addition expression to the specified object.
     * The result is true if and only if the argument is not null, the argument is instance of Addition expression and the sub-expressions are equals.
     *
     * @param other The object to compare this expression against
     * @return true if the given object represents an expression equivalent to this expression, false otherwise
     */
    public boolean equals(Object other) {
        return ((other instanceof Addition) &&
                (ex1.equals(((Addition) other).ex1)) &&
                (ex2.equals(((Addition) other).ex2)));
    }

    /**
     * Returns a string representing the Addition Expression.
     *
     * @return String that represents the Addition Expression
     */
    public String toString() {
        return "(" + ex1.toString() + getLastOperationSymbol() + ex2.toString() + ")";
 }
	/**
	 * Replicating the invoking object.
	 * 
	 * @return a replicate of this object. The returned object has
	 * to be a new object (with a different address than this
	 * object), but equivalent to the this object under the 
	 * application of the {@code equals(Object other)} method.
	 */
	public Expression replicate(){
		return new Addition(ex1,ex2);
	}

}
